from fastapi import APIRouter, UploadFile, File, Form, HTTPException, BackgroundTasks, Request
from fastapi.responses import FileResponse, JSONResponse
import os
import shutil
import uuid
import logging
from typing import Optional, List, Dict
from pydantic import BaseModel
import traceback

from pp_docTranslation_utils import translate_document

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

router = APIRouter()

# 定义基础输出目录
BASE_OUTPUT_DIR = "output_files"
TEMP_DIR = os.path.join(BASE_OUTPUT_DIR, "temp")

class TranslationResponse(BaseModel):
    success: bool
    message: str
    output_files: List[str] = []
    file_urls: List[str] = []
    error: Optional[str] = None
    task_id: Optional[str] = None

def get_file_url(request: Request, relative_path: str) -> str:
    """构建完整的URL，包含协议、主机名和端口"""
    base_url = str(request.base_url)
    if base_url.endswith('/'):
        base_url = base_url[:-1]
    
    # 确保相对路径以/开头
    if not relative_path.startswith('/'):
        relative_path = '/' + relative_path
    
    return f"{base_url}{relative_path}"

@router.post("/translate_file", response_model=TranslationResponse)
async def translate_file(
    file: UploadFile = File(...),
    target_language: str = Form("zh"),
    background_tasks: BackgroundTasks = None,
    request: Request = None
):
    """
    翻译上传的文档
    
    - **file**: 要翻译的PDF或Markdown文件
    - **target_language**: 目标语言（默认：zh，支持：zh, en等）
    """
    # 创建唯一ID作为任务ID和临时目录
    task_id = str(uuid.uuid4())
    task_dir = os.path.join(TEMP_DIR, task_id)
    input_dir = os.path.join(task_dir, "input")
    output_dir = os.path.join(task_dir, "output")
    
    # 确保目录存在
    try:
        os.makedirs(TEMP_DIR, exist_ok=True)
        os.makedirs(input_dir, exist_ok=True)
        os.makedirs(output_dir, exist_ok=True)
        logger.info(f"成功创建目录结构: {task_dir}")
    except Exception as e:
        logger.error(f"创建目录失败: {str(e)}")
        return JSONResponse(
            status_code=500,
            content={
                "success": False,
                "message": f"创建目录失败: {str(e)}",
                "output_files": [],
                "file_urls": [],
                "error": str(e),
                "task_id": task_id
            }
        )
    
    # 保存上传的文件
    file_path = os.path.join(input_dir, file.filename)
    try:
        with open(file_path, "wb") as f:
            shutil.copyfileobj(file.file, f)
        logger.info(f"成功保存上传的文件: {file_path}")
    except Exception as e:
        logger.error(f"无法保存上传的文件: {str(e)}")
        return JSONResponse(
            status_code=500,
            content={
                "success": False,
                "message": f"无法保存上传的文件: {str(e)}",
                "output_files": [],
                "file_urls": [],
                "error": str(e),
                "task_id": task_id
            }
        )
    finally:
        file.file.close()
    
    # 检查文件类型
    if not (file_path.lower().endswith(".pdf") or file_path.lower().endswith(".md")):
        shutil.rmtree(task_dir)
        return JSONResponse(
            status_code=400,
            content={
                "success": False,
                "message": "只支持PDF或Markdown文件",
                "output_files": [],
                "file_urls": [],
                "error": "不支持的文件类型",
                "task_id": task_id
            }
        )
    
    logger.info(f"文件 '{file.filename}' 上传成功，任务ID: {task_id}")
    
    # 直接处理文件（非后台任务）
    try:
        result = translate_document(
            input_path=file_path,
            output_path=output_dir,
            target_language=target_language
        )
        
        # 添加任务ID到结果
        result["task_id"] = task_id
        
        # 将本地文件路径转换为完整的HTTP URL路径
        file_urls = []
        for file_path in result["output_files"]:
            if os.path.exists(file_path):
                try:
                    rel_path = os.path.relpath(file_path, BASE_OUTPUT_DIR)
                    url_path = f"/files/{rel_path.replace(os.sep, '/')}"
                    # 构建完整URL
                    full_url = get_file_url(request, url_path)
                    file_urls.append(full_url)
                    logger.info(f"文件URL: {full_url}")
                except Exception as e:
                    logger.error(f"创建文件URL出错: {str(e)}")
        
        result["file_urls"] = file_urls
        
        return result
    except Exception as e:
        logger.error(f"翻译过程发生错误: {str(e)}")
        logger.error(traceback.format_exc())
        return {
            "success": False,
            "message": f"翻译过程发生错误",
            "output_files": [],
            "file_urls": [],
            "error": str(e),
            "task_id": task_id
        }

@router.get("/translation_status/{task_id}", response_model=TranslationResponse)
async def get_translation_status(task_id: str, request: Request = None):
    """
    获取翻译任务状态
    
    - **task_id**: 翻译任务ID
    """
    task_dir = os.path.join(TEMP_DIR, task_id)
    output_dir = os.path.join(task_dir, "output")
    
    if not os.path.exists(task_dir):
        raise HTTPException(status_code=404, detail=f"任务ID {task_id} 不存在")
    
    # 检查输出目录中的文件
    output_files = []
    file_urls = []
    if os.path.exists(output_dir):
        for f in os.listdir(output_dir):
            if f.endswith(".md"):
                file_path = os.path.join(output_dir, f)
                if os.path.exists(file_path) and os.path.getsize(file_path) > 0:
                    output_files.append(str(file_path))
                    
                    # 创建完整URL
                    try:
                        rel_path = os.path.relpath(file_path, BASE_OUTPUT_DIR)
                        url_path = f"/files/{rel_path.replace(os.sep, '/')}"
                        full_url = get_file_url(request, url_path)
                        file_urls.append(full_url)
                    except Exception as e:
                        logger.error(f"创建文件URL出错: {str(e)}")
    
    return {
        "success": len(output_files) > 0,
        "message": "翻译已完成" if len(output_files) > 0 else "翻译正在进行中",
        "output_files": output_files,
        "file_urls": file_urls,
        "task_id": task_id
    }

@router.get("/files/{task_id}/{file_name}", include_in_schema=False)
async def get_file(task_id: str, file_name: str):
    """
    直接获取文件内容
    """
    file_path = os.path.join(TEMP_DIR, task_id, "output", file_name)
    if not os.path.exists(file_path):
        raise HTTPException(status_code=404, detail="文件不存在")
    return FileResponse(file_path)

@router.get("/download_translation/{task_id}/{file_name}")
async def download_translation(task_id: str, file_name: str):
    """
    下载翻译结果文件
    
    - **task_id**: 翻译任务ID
    - **file_name**: 文件名
    """
    file_path = os.path.join(TEMP_DIR, task_id, "output", file_name)
    
    if not os.path.exists(file_path):
        raise HTTPException(status_code=404, detail=f"文件不存在")
    
    # 返回文件响应，允许下载
    return FileResponse(
        path=file_path, 
        filename=file_name, 
        media_type="text/markdown"
    ) 